#pragma once
#include "ThreadCache.h"
#include "PageCache.h"
#include "ObjectPool.h"

static void* ConcurrentAllocate(size_t size)
{
	if (size > MAX_BYTES)
	{
		size_t roundUpSize = SizeClass::RoundUp(size);
		size_t kPage = roundUpSize >> PAGE_SHIFT;
		PageCache::GetInstance()->mtx_.lock();
		Span* span = PageCache::GetInstance()->NewSpan(kPage);
		span->objectSize_ = kPage << PAGE_SHIFT;
		span->isUse_ = true;
		PageCache::GetInstance()->mtx_.unlock();
		void* ret = reinterpret_cast<void*>(span->id_ << PAGE_SHIFT);
		return ret;
	}
	else
	{
		if (pThreadCache == nullptr)
		{
			static ObjectPool<ThreadCache> threadPool;
			pThreadCache = threadPool.New();
		}
		//cout << std::this_thread::get_id() << ":" << pThreadCache << endl;
		return pThreadCache->Allocate(size);
	}
	
}

static void ConcurrentDeAllocate(void* obj)
{
	Span* span = PageCache::GetInstance()->MapObjectToSpan(obj);
	size_t size = span->objectSize_;
	if (size > MAX_BYTES)
	{
		PageCache::GetInstance()->mtx_.lock();
		PageCache::GetInstance()->ReleaseSpanToPageCache(span);
		PageCache::GetInstance()->mtx_.unlock();
	}
	else
	{
		pThreadCache->DeAllocate(obj, size);
	}
}